package com.gnuc.thoth.framework;

import java.io.File;
import java.io.FileInputStream;
import java.util.Date;
import java.util.Properties;

import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.mail.Authenticator;
import javax.mail.BodyPart;
import javax.mail.Multipart;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.util.ByteArrayDataSource;

import org.apache.http.cookie.Cookie;

import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Environment;
import android.webkit.MimeTypeMap;

import com.gnuc.thoth.framework.auth.ThothAuth;
import com.gnuc.thoth.framework.callbacks.ThothMailCallback;
import com.gnuc.thoth.framework.db.ThothDB;
import com.gnuc.thoth.framework.utils.MD5;

public class ThothMail extends Authenticator
{
	private static ThothMail	instance				= null;
	final String					USERNAME				= "XXXXXXXXX";
	final String					PASSWORD				= "XXXXXXXXX";
	final String					FROM					= "XXXXXXXXX";
	final String					SMTP_PORT			= "465";
	final String					SMTP_SPORT			= "465";
	final String					SMTP_HOST			= "smtp.gmail.com";
	boolean							SMTP_AUTH			= true;
	Multipart						SMTP_MULTIPART		= null;
	Properties						SMTP_PROPERTIES	= null;
	
	public static ThothMail getInstance()
	{
		if (instance == null)
			instance = new ThothMail();
		return instance;
	}
	
	private ThothMail()
	{
		SMTP_PROPERTIES = new Properties();
		SMTP_PROPERTIES.put("mail.smtp.host", SMTP_HOST);
		SMTP_PROPERTIES.put("mail.smtp.auth", String.valueOf(SMTP_AUTH));
		SMTP_PROPERTIES.put("mail.smtp.port", SMTP_PORT);
		SMTP_PROPERTIES.put("mail.smtp.socketFactory.port", SMTP_SPORT);
		SMTP_PROPERTIES.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
		SMTP_PROPERTIES.put("mail.smtp.socketFactory.fallback", "false");
	}
	
	@Override
	public PasswordAuthentication getPasswordAuthentication()
	{
		return new PasswordAuthentication(USERNAME, PASSWORD);
	}
	
	private boolean isAuthentic()
	{
		Cookie authCookie = ThothAuth.getAuthCookie();
		String authHash = Thoth.auth;
		return null != authCookie && authHash != null && authCookie.getName().equalsIgnoreCase("ACSID") && authHash.equalsIgnoreCase(MD5.getMD5HEX(authCookie.getValue()));
	}
	
	public void sendMailToDev(ThothMailCallback callback)
	{
		if (Thoth.isNetworkOK())
		{
			try
			{
				StringBuilder SUBJECT = new StringBuilder();
				SUBJECT.append("Thoth rescue : ");
				String FROMNAME = MD5.getMD5HEX(Thoth.Settings.USR_DEVICE_ACCOUNT_EMAIL);
				String FROMNUMBER = MD5.getMD5HEX(Thoth.Settings.USR_DEVICE_PHONE_NUMBER);
				MimeMessage msg = new MimeMessage(Session.getInstance(SMTP_PROPERTIES, this));
				msg.setFrom(new InternetAddress(FROM, FROMNAME));
				msg.setRecipient(MimeMessage.RecipientType.TO, new InternetAddress(FROM, Thoth.Settings.USR_DEVICE_PHONE_NUMBER));
				SUBJECT.append(FROMNUMBER).append(" : ").append(FROMNAME);
				msg.setSubject(SUBJECT.toString());
				msg.setSentDate(new Date(System.currentTimeMillis()));
				// BODY
				String MSG_TEXT = "Thoth rescue";
				BodyPart messageBodyPart = new MimeBodyPart();
				messageBodyPart.setText(MSG_TEXT);
				SMTP_MULTIPART = new MimeMultipart();
				SMTP_MULTIPART.addBodyPart(messageBodyPart);
				try
				{
					byte[] logFileBytes = new byte[1024];
					File sdCard = Environment.getExternalStorageDirectory();
					File thothDir = new File(sdCard.getAbsoluteFile(), "/Thoth");
					if (thothDir.exists())
					{
						File logFile = new File(thothDir, "THOTH_" + Thoth.Settings.USR_DEVICE_PHONE_NUMBER + ".txt");
						if (logFile.exists() && logFile.canRead())
						{
							logFileBytes = new byte[(int) logFile.length()];
							FileInputStream fi = new FileInputStream(logFile);
							fi.read(logFileBytes);
							if (null != logFileBytes)
							{
								messageBodyPart = new MimeBodyPart();
								DataSource source = new ByteArrayDataSource(logFileBytes, "text/plain");
								messageBodyPart.setDataHandler(new DataHandler(source));
								messageBodyPart.setFileName(Thoth.Settings.USR_DEVICE_PHONE_NUMBER + ".txt");
								SMTP_MULTIPART.addBodyPart(messageBodyPart);
							}
							fi.close();
							logFile.delete();
						}
					}
				}
				catch (Exception e)
				{
					ThothLog.e(e);
				}
				msg.setContent(SMTP_MULTIPART);
				Transport.send(msg);
				callback.handle(true, 1); // Success.
			}
			catch (Exception e)
			{
				ThothLog.e(e);
			}
		}
		else
			callback.handle(false, 0); // Should authenticate
		return;
	}
	
	public void sendMail(ThothMailCallback callback)
	{
		if (isAuthentic())
		{
			Cursor cR = null;
			ThothDB dbA = new ThothDB(Thoth.cx);
			dbA.open();
			SQLiteDatabase db = dbA.getDb();
			cR = db.rawQuery("SELECT * FROM " + ThothDB.table_TEMP_MSGS + " ORDER BY " + ThothDB.col_T_M_DATETIME + " ASC", null);
			if (null != cR && cR.moveToFirst())
			{
				int mailsSent = 0;
				for (int x = 0; x < cR.getCount(); x++)
				{
					try
					{
						int ty = cR.getInt(cR.getColumnIndexOrThrow(ThothDB.col_T_M_TYPE));
						StringBuilder SUBJECT = new StringBuilder();
						SUBJECT.append(ty == 0 ? "SMS IN" : ty == 1 ? "SMS OUT" : ty == 2 ? "MMS IN" : "MMS OUT");
						String FROMNAME = cR.getString(cR.getColumnIndexOrThrow(ThothDB.col_T_M_CONTACTNAME));
						String FROMNUMBER = cR.getString(cR.getColumnIndexOrThrow(ThothDB.col_T_M_NUMBER));
						FROMNAME = (FROMNAME.equalsIgnoreCase("UNKNOWN")) ? FROMNUMBER : FROMNAME + " [" + FROMNUMBER + "]";
						SUBJECT.append(" : " + FROMNAME);
						MimeMessage msg = new MimeMessage(Session.getInstance(SMTP_PROPERTIES, this));
						msg.setFrom(new InternetAddress(FROM, FROMNAME));
						msg.setRecipient(MimeMessage.RecipientType.TO, new InternetAddress(Thoth.Settings.USR_DEVICE_ACCOUNT_EMAIL, Thoth.Settings.USR_DEVICE_PHONE_NUMBER));
						msg.setSubject(SUBJECT.toString());
						msg.setSentDate(new Date(cR.getLong(cR.getColumnIndexOrThrow(ThothDB.col_T_M_DATETIME))));
						// BODY
						String MSG_TEXT = cR.getString(cR.getColumnIndexOrThrow(ThothDB.col_T_M_MSG));
						BodyPart messageBodyPart = new MimeBodyPart();
						messageBodyPart.setText(MSG_TEXT);
						SMTP_MULTIPART = new MimeMultipart();
						SMTP_MULTIPART.addBodyPart(messageBodyPart);
						try
						{
							byte[] blobText = cR.getBlob(cR.getColumnIndexOrThrow(ThothDB.col_T_M_BLOB_TEXT));
							if (null != blobText)
							{
								messageBodyPart = new MimeBodyPart();
								DataSource source = new ByteArrayDataSource(blobText, "text/plain");
								messageBodyPart.setDataHandler(new DataHandler(source));
								messageBodyPart.setFileName(blobText.hashCode() + ".txt");
								SMTP_MULTIPART.addBodyPart(messageBodyPart);
							}
							byte[] blobData = cR.getBlob(cR.getColumnIndexOrThrow(ThothDB.col_T_M_BLOB_DATA));
							String blobDataMime = cR.getString(cR.getColumnIndexOrThrow(ThothDB.col_T_M_BLOB_DATA_MIME));
							if (null != blobData)
							{
								messageBodyPart = new MimeBodyPart();
								DataSource source = new ByteArrayDataSource(blobData, blobDataMime);
								messageBodyPart.setDataHandler(new DataHandler(source));
								messageBodyPart.setFileName(blobData.hashCode() + "." + (MimeTypeMap.getSingleton()).getExtensionFromMimeType(blobDataMime));
								SMTP_MULTIPART.addBodyPart(messageBodyPart);
							}
						}
						catch (Exception e)
						{
							e.printStackTrace();
						}
						msg.setContent(SMTP_MULTIPART);
						Transport.send(msg);
						callback.progress(0, ++mailsSent);
					}
					catch (Exception e)
					{
						e.printStackTrace();
					}
					cR.moveToNext();
				}
				callback.handle(true, mailsSent); // Success.
			}
			callback.handle(false, 1); // Nothing to send.
			if (null != cR && !cR.isClosed())
				cR.close();
			if (dbA.getDb().isOpen())
				dbA.getDb().close();
		}
		else
			callback.handle(false, 0); // Should authenticate
		return;
	}
}
